home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ada / gwuada_5.zip / adaed / nyudemos / diners1.ada < prev    next >
Text File  |  1992-09-01  |  8KB  |  326 lines

  1. --::::::::::
  2. --io_libs.ada
  3. --::::::::::
  4. -- Precompiled instantiations of Integer_IO and
  5. -- Float_IO for the predefined Integer and Float types
  6.  
  7. WITH Text_IO;
  8. PACKAGE My_Int_IO IS
  9.   NEW Text_IO.Integer_IO (Num => Integer);
  10.  
  11. WITH Text_IO;
  12. PACKAGE My_Flt_IO IS
  13.   NEW Text_IO.Float_IO   (Num => Float);
  14. --::::::::::
  15. --random.ads
  16. --::::::::::
  17. PACKAGE Random IS
  18.  
  19. -- Simple pseudo-random number generator package.
  20. -- Adapated from the Ada literature by
  21. -- Michael B. Feldman, The George Washington University, November 1990.
  22.  
  23.   PROCEDURE Set_Seed (N : Positive);
  24.  
  25.   FUNCTION  Unit_Random RETURN Float;
  26.  
  27.     --returns a float >=0.0 and <1.0
  28.  
  29.   FUNCTION  Random_Int (N : Positive) RETURN Positive;
  30.  
  31.     --return a random integer in the range 1..N
  32.  
  33. END Random;
  34. --::::::::::
  35. --chop.ads
  36. --::::::::::
  37. PACKAGE Chop IS
  38.  
  39.   TASK TYPE Stick IS
  40.     ENTRY Pick_Up;
  41.     ENTRY Put_Down;
  42.   END Stick;
  43.  
  44. END Chop;
  45. --::::::::::
  46. --phil.ads
  47. --::::::::::
  48. PACKAGE Phil IS
  49.   
  50.   TASK TYPE Philosopher IS
  51.     
  52.     ENTRY Come_To_Life (My_ID :      Positive; 
  53.                         Chopstick1 : Positive;
  54.                         Chopstick2 : Positive);
  55.  
  56.   END Philosopher;
  57.  
  58.   TYPE States IS (Breathing, Thinking, Eating, Done_Eating,
  59.                     Got_One_Stick, Got_Other_Stick);
  60.  
  61. END Phil;
  62. --::::::::::
  63. --room.ads
  64. --::::::::::
  65. WITH Chop;
  66. WITH Phil;
  67. PACKAGE Room IS
  68.  
  69.   Table_Size: CONSTANT := 5;
  70.   SUBTYPE Table_Type IS Positive RANGE 1..Table_Size;
  71.  
  72.   Sticks:     ARRAY(Table_Type) OF Chop.Stick;
  73.  
  74.   TASK Head_Waiter IS
  75.     ENTRY Open_The_Room;
  76.     ENTRY Report_State(Which_Phil: Table_Type;
  77.                        State: Phil.States;
  78.                        How_Long: Natural := 0);
  79.   END Head_Waiter;
  80.  
  81. END Room;
  82. --::::::::::
  83. --diners.ada
  84. --::::::::::
  85. WITH Room;
  86. PROCEDURE Diners IS
  87.  
  88. BEGIN
  89.   Room.Head_Waiter.Open_The_Room;
  90.   LOOP
  91.     DELAY 20.0;
  92.   END LOOP;
  93. END Diners;
  94. --::::::::::
  95. --random.adb
  96. --::::::::::
  97. WITH Calendar;
  98. USE  Calendar;
  99.  
  100. PACKAGE BODY Random IS
  101.  
  102. -- Body of random number generator package.
  103. -- Adapted from the Ada literature by
  104. -- Michael B. Feldman, The George Washington University, November 1990.
  105.  
  106.   Modulus      : CONSTANT := 9317;
  107.  
  108.   TYPE Int_16 IS RANGE - 2 ** 15 .. 2 ** 15 - 1;
  109.  
  110.   TYPE Int_32 IS RANGE - 2 ** 31 .. 2 ** 31 - 1;
  111.  
  112.   SUBTYPE Seed_Range IS Int_16 RANGE 0 .. (Modulus - 1);
  113.  
  114.   Seed,
  115.   Default_Seed : Seed_Range;
  116.  
  117.   PROCEDURE Set_Seed (N : Positive) IS SEPARATE;
  118.  
  119.   FUNCTION  Unit_Random RETURN Float IS SEPARATE;
  120.  
  121.   FUNCTION  Random_Int (N : Positive) RETURN Positive IS SEPARATE;
  122. BEGIN
  123.   Default_Seed := Int_16 (Int_32 (Seconds (Clock)) MOD Modulus);
  124.   Seed := Default_Seed;
  125. END Random;
  126.  
  127. SEPARATE (Random)
  128.  
  129. PROCEDURE Set_Seed (N : Positive) IS
  130. BEGIN
  131.   Seed := Seed_Range (N);
  132. END Set_Seed;
  133.  
  134. SEPARATE (Random)
  135.  
  136. FUNCTION  Unit_Random RETURN Float IS
  137.   Multiplier : CONSTANT := 421;
  138.   Increment  : CONSTANT := 2073;
  139.   Result     : Float;
  140. BEGIN
  141.   Seed := (Multiplier * Seed + Increment) MOD Modulus;
  142.   Result := Float (Seed) / Float (Modulus);
  143.   RETURN Result;
  144. EXCEPTION
  145.   WHEN Constraint_Error | Numeric_Error =>
  146.     Seed := Int_16 ((Multiplier * Int_32 (Seed) + Increment) MOD Modulus);
  147.     Result := Float (Seed) / Float (Modulus);
  148.     RETURN Result;
  149.  
  150. END Unit_Random;
  151.  
  152. SEPARATE (Random)
  153.  
  154. FUNCTION  Random_Int (N : Positive) RETURN Positive IS
  155.   Result : Integer RANGE 1 .. N;
  156. BEGIN
  157.   Result := Integer (Float (N) * Unit_Random + 0.5);
  158.   RETURN Result;
  159. EXCEPTION
  160.   WHEN Constraint_Error | Numeric_Error =>
  161.     RETURN 1;
  162.  
  163. END Random_Int;
  164. --::::::::::
  165. --chop.adb
  166. --::::::::::
  167. PACKAGE BODY Chop IS
  168.  
  169.   TASK BODY Stick IS
  170.  
  171.   BEGIN
  172.     
  173.     LOOP
  174.       SELECT
  175.         ACCEPT Pick_Up;
  176.         ACCEPT Put_Down;
  177.       OR
  178.         TERMINATE;
  179.       END SELECT;
  180.     END LOOP;
  181.  
  182.   END Stick;
  183.  
  184. END Chop;
  185. --::::::::::
  186. --phil.adb
  187. --::::::::::
  188. WITH Room;
  189. WITH Random;
  190. PACKAGE BODY Phil IS
  191.   
  192.   TASK BODY Philosopher IS
  193.  
  194.     Who_Am_I   : Positive;
  195.     First_Grab : Positive;
  196.     Second_Grab: Positive;
  197.     Meal_Time  : Natural;
  198.     Think_Time : Natural;
  199.     
  200.   BEGIN
  201.     ACCEPT Come_To_Life (My_ID :     Positive; 
  202.                         Chopstick1 : Positive;
  203.                         Chopstick2 : Positive) DO
  204.       Who_Am_I    := My_ID;
  205.       First_Grab  := Chopstick1;
  206.       Second_Grab := Chopstick2;
  207.  
  208.     END Come_To_Life;
  209.  
  210.     Room.Head_Waiter.Report_State(Who_Am_I, Breathing);
  211.  
  212.     LOOP
  213.  
  214.       Room.Sticks(First_Grab).Pick_Up;
  215.       Room.Head_Waiter.Report_State(Who_Am_I, Got_One_Stick, First_Grab);
  216.  
  217.       Room.Sticks(Second_Grab).Pick_Up;
  218.       Room.Head_Waiter.Report_State(Who_Am_I, Got_Other_Stick, Second_Grab);
  219.  
  220.       Meal_Time := Random.Random_Int(10);
  221.       Room.Head_Waiter.Report_State(Who_Am_I, Eating, Meal_Time);
  222.  
  223.       DELAY Duration(Meal_Time);
  224.       Room.Head_Waiter.Report_State(Who_Am_I, Done_Eating);
  225.  
  226.       Room.Sticks(First_Grab).Put_Down;
  227.       Room.Sticks(Second_Grab).Put_Down;
  228.  
  229.       Think_Time := Random.Random_Int(10);
  230.       Room.Head_Waiter.Report_State(Who_Am_I, Thinking, Think_Time);
  231.       DELAY Duration(Think_Time);
  232.  
  233.     END LOOP;
  234.  
  235.   END Philosopher;
  236.  
  237. END Phil;
  238. --::::::::::
  239. --roomline.adb
  240. --::::::::::
  241. WITH Text_IO;
  242. WITH Chop;
  243. WITH Phil;
  244. WITH Calendar;
  245. PRAGMA Elaborate(Phil);
  246. PACKAGE BODY Room IS
  247.  
  248. -- A line-oriented version of the Room package, for line-oriented
  249. -- terminals like IBM 3270's where the user cannot do ASCII screen control.
  250. -- This is the only file in the dining philosophers system that needs
  251. -- changing to use in a line-oriented environment.
  252. -- Michael B. Feldman, The George Washington University, November 1990.
  253.  
  254.  
  255.   Phils:      ARRAY(Table_Type) OF Phil.Philosopher;
  256.  
  257.   TYPE Phil_Names IS (Dijkstra, Texel, Booch, Ichbiah, Stroustrup);
  258.  
  259.   TASK BODY Head_Waiter IS
  260.  
  261.     T : Integer;
  262.     Start_Time: Calendar.Time;
  263.     Phil_Names: CONSTANT ARRAY(1..5) OF String(1..18) :=
  264.      ("Eddy Dijkstra     ",
  265.       "Putnam Texel      ",
  266.       "Grady Booch       ",
  267.       "Jean Ichbiah      ",
  268.       "Bjarne Stroustrup ");
  269.     Blanks : CONSTANT String := "     ";
  270.  
  271.   BEGIN
  272.  
  273.     ACCEPT Open_The_Room;
  274.     Start_Time := Calendar.Clock;
  275.  
  276.     Phils(1).Come_To_Life(1,1,2);
  277.     Phils(3).Come_To_Life(3,3,4);
  278.     Phils(2).Come_To_Life(2,2,3);
  279.     Phils(5).Come_To_Life(5,1,5);
  280.     Phils(4).Come_To_Life(4,4,5);
  281.  
  282.     LOOP
  283.       SELECT
  284.         ACCEPT Report_State(Which_Phil: Table_Type;
  285.                          State: Phil.States;
  286.                          How_Long: Natural := 0) DO
  287.           T := Integer(Calendar."-"(Calendar.Clock,Start_Time));
  288.           Text_IO.Put( "T=" & Integer'Image(T) & " "
  289.             & Blanks(1..Which_Phil) & Phil_Names(Which_Phil));
  290.  
  291.           CASE State IS
  292.  
  293.             WHEN Phil.Breathing =>
  294.               Text_IO.Put("Breathing");
  295.             WHEN Phil.Thinking =>
  296.               Text_IO.Put( "Thinking"
  297.                          & Integer'Image(How_Long)
  298.                          & " seconds.");
  299.             WHEN Phil.Eating =>
  300.               Text_IO.Put( "Eating"
  301.                          & Integer'Image(How_Long)
  302.                          & " seconds.");
  303.             WHEN Phil.Done_Eating =>
  304.               Text_IO.Put("Yum-yum (burp)");
  305.             WHEN Phil.Got_One_Stick =>
  306.               Text_IO.Put( "First chopstick"
  307.                           & Integer'Image(How_Long));
  308.             WHEN Phil.Got_Other_Stick =>
  309.               Text_IO.Put( "Second chopstick"
  310.                           & Integer'Image(How_Long));
  311.  
  312.           END CASE;
  313.           Text_IO.New_Line;
  314.  
  315.          END Report_State;
  316.         OR
  317.           TERMINATE;
  318.         END SELECT;
  319.  
  320.       END LOOP;
  321.  
  322.     END Head_Waiter;
  323.  
  324. END Room;
  325.  
  326.